export interface ImageProcessorOptions {
  format: 'jpeg' | 'png' | 'webp'
  quality: number
  width?: number
  height?: number
}

export class ImageProcessor {
  private canvas: HTMLCanvasElement
  private ctx: CanvasRenderingContext2D

  constructor() {
    this.canvas = document.createElement('canvas')
    const ctx = this.canvas.getContext('2d')
    if (!ctx) {
      throw new Error('Canvas context not supported')
    }
    this.ctx = ctx
  }

  async processImage(file: File, options: ImageProcessorOptions): Promise<Blob> {
    const image = await this.loadImage(file)
    this.setCanvasSize(image, options)
    this.ctx.drawImage(image, 0, 0, this.canvas.width, this.canvas.height)

    return new Promise((resolve, reject) => {
      this.canvas.toBlob(
        (blob) => {
          if (blob) {
            resolve(blob)
          } else {
            reject(new Error('Failed to process image'))
          }
        },
        `image/${options.format}`,
        options.quality / 100
      )
    })
  }

  private loadImage(file: File): Promise<HTMLImageElement> {
    return new Promise((resolve, reject) => {
      const image = new Image()
      image.onload = () => resolve(image)
      image.onerror = reject
      image.src = URL.createObjectURL(file)
    })
  }

  private setCanvasSize(image: HTMLImageElement, options: ImageProcessorOptions) {
    let width = image.width
    let height = image.height

    if (options.width && options.height) {
      width = options.width
      height = options.height
    } else if (options.width) {
      height = (options.width / image.width) * image.height
      width = options.width
    } else if (options.height) {
      width = (options.height / image.height) * image.width
      height = options.height
    }

    this.canvas.width = width
    this.canvas.height = height
  }

  async getImageInfo(file: File): Promise<{
    width: number
    height: number
    size: number
    type: string
  }> {
    const image = await this.loadImage(file)
    return {
      width: image.width,
      height: image.height,
      size: file.size,
      type: file.type
    }
  }
} 